<?php
/**
 * 缓存管理服务
 * 统一管理系统所有缓存操作
 */

declare(strict_types=1);

namespace app\service;

use think\facade\Cache;
use think\facade\Log;

class CacheManagerService
{
    /**
     * 缓存配置
     */
    private const CACHE_CONFIGS = [
        'workflow' => [
            'prefix' => 'workflow:',
            'ttl' => 3600,
            'tags' => ['workflow']
        ],
        'permission' => [
            'prefix' => 'permission:',
            'ttl' => 7200,
            'tags' => ['permission']
        ],
        'user' => [
            'prefix' => 'user:',
            'ttl' => 1800,
            'tags' => ['user']
        ],
        'stats' => [
            'prefix' => 'stats:',
            'ttl' => 300,
            'tags' => ['stats']
        ],
        'system' => [
            'prefix' => 'system:',
            'ttl' => 86400,
            'tags' => ['system']
        ]
    ];

    /**
     * 缓存键模板
     */
    private const CACHE_KEY_TEMPLATES = [
        // 工作流相关
        'workflow_detail' => 'workflow:detail:%s',
        'workflow_pending' => 'workflow:pending:%s:%s:%s:%s',
        'workflow_stats' => 'workflow:stats:%s',
        
        // 权限相关
        'permission_user_info' => 'permission:user_info:%s',
        'permission_user_permissions' => 'permission:user_permissions:%s:%s',
        'permission_access_check' => 'permission:access_check:%s:%s:%s',
        'permission_conditions' => 'permission:conditions:%s:%s',
        
        // 用户相关
        'user_profile' => 'user:profile:%s',
        'user_departments' => 'user:departments:%s',
        'user_roles' => 'user:roles:%s',
        
        // 统计相关
        'stats_dashboard' => 'stats:dashboard:%s',
        'stats_module' => 'stats:module:%s:%s',
        
        // 系统相关
        'system_config' => 'system:config:%s',
        'system_dict' => 'system:dict:%s'
    ];

    /**
     * 获取缓存
     */
    public function get(string $template, ...$params)
    {
        $key = $this->buildKey($template, $params);
        $result = Cache::get($key);
        
        if ($result !== null) {
            Log::debug("缓存命中: $key");
        }
        
        return $result;
    }

    /**
     * 设置缓存
     */
    public function set(string $template, $data, ...$params): bool
    {
        $key = $this->buildKey($template, $params);
        $category = $this->getCategoryFromTemplate($template);
        $config = self::CACHE_CONFIGS[$category] ?? self::CACHE_CONFIGS['system'];
        
        $result = Cache::set($key, $data, $config['ttl']);
        
        if ($result) {
            Log::debug("缓存设置: $key, TTL: {$config['ttl']}");
        }
        
        return $result;
    }

    /**
     * 删除缓存
     */
    public function delete(string $template, ...$params): bool
    {
        $key = $this->buildKey($template, $params);
        $result = Cache::delete($key);
        
        Log::debug("缓存删除: $key");
        
        return $result;
    }

    /**
     * 清理匹配模式的缓存
     */
    public function clear(string $pattern): bool
    {
        $result = Cache::clear($pattern);
        
        Log::info("批量缓存清理: $pattern");
        
        return $result;
    }

    /**
     * 按标签清理缓存
     */
    public function clearByTag(string $tag): bool
    {
        $result = Cache::tag($tag)->clear();
        
        Log::info("按标签清理缓存: $tag");
        
        return $result;
    }

    /**
     * 按分类清理缓存
     */
    public function clearByCategory(string $category): bool
    {
        if (!isset(self::CACHE_CONFIGS[$category])) {
            return false;
        }
        
        $config = self::CACHE_CONFIGS[$category];
        $pattern = $config['prefix'] . '*';
        
        return $this->clear($pattern);
    }

    /**
     * 清理用户相关的所有缓存
     */
    public function clearUserCache(int $userId): bool
    {
        $patterns = [
            sprintf('workflow:*:%s:*', $userId),
            sprintf('permission:*:%s*', $userId),
            sprintf('user:*:%s', $userId),
            sprintf('stats:*:%s', $userId)
        ];
        
        foreach ($patterns as $pattern) {
            $this->clear($pattern);
        }
        
        Log::info("清理用户缓存: $userId");
        
        return true;
    }

    /**
     * 清理工作流相关缓存
     */
    public function clearWorkflowCache(int $approvalId = null, int $userId = null): bool
    {
        if ($approvalId) {
            // 清理特定审批的缓存
            $this->delete('workflow_detail', $approvalId);
        }
        
        if ($userId) {
            // 清理用户相关的工作流缓存
            $patterns = [
                sprintf('workflow:pending:%s:*', $userId),
                sprintf('workflow:stats:%s', $userId)
            ];
            
            foreach ($patterns as $pattern) {
                $this->clear($pattern);
            }
        }
        
        if (!$approvalId && !$userId) {
            // 清理所有工作流缓存
            $this->clearByCategory('workflow');
        }
        
        return true;
    }

    /**
     * 清理权限相关缓存
     */
    public function clearPermissionCache(int $userId = null, string $module = null): bool
    {
        if ($userId && $module) {
            // 清理特定用户和模块的权限缓存
            $patterns = [
                sprintf('permission:user_permissions:%s:%s', $userId, $module),
                sprintf('permission:conditions:%s:%s', $userId, $module),
                sprintf('permission:access_check:%s:%s:*', $userId, $module)
            ];
            
            foreach ($patterns as $pattern) {
                $this->clear($pattern);
            }
        } elseif ($userId) {
            // 清理特定用户的权限缓存
            $patterns = [
                sprintf('permission:user_info:%s', $userId),
                sprintf('permission:user_permissions:%s:*', $userId),
                sprintf('permission:conditions:%s:*', $userId),
                sprintf('permission:access_check:%s:*', $userId)
            ];
            
            foreach ($patterns as $pattern) {
                $this->clear($pattern);
            }
        } else {
            // 清理所有权限缓存
            $this->clearByCategory('permission');
        }
        
        return true;
    }

    /**
     * 缓存预热
     */
    public function warmup(array $options = []): bool
    {
        Log::info("开始缓存预热", $options);
        
        try {
            // 预热系统配置
            $this->warmupSystemCache();
            
            // 预热活跃用户数据
            if (!empty($options['active_users'])) {
                $this->warmupUserCache($options['active_users']);
            }
            
            // 预热统计数据
            if (!empty($options['stats'])) {
                $this->warmupStatsCache();
            }
            
            Log::info("缓存预热完成");
            return true;
        } catch (\Exception $e) {
            Log::error("缓存预热失败: " . $e->getMessage());
            return false;
        }
    }

    /**
     * 获取缓存统计信息
     */
    public function getStats(): array
    {
        $stats = [];
        
        foreach (self::CACHE_CONFIGS as $category => $config) {
            $pattern = $config['prefix'] . '*';
            $keys = $this->getKeysByPattern($pattern);
            
            $stats[$category] = [
                'prefix' => $config['prefix'],
                'ttl' => $config['ttl'],
                'count' => count($keys),
                'memory_usage' => $this->estimateMemoryUsage($keys)
            ];
        }
        
        return $stats;
    }

    /**
     * 构建缓存键
     */
    private function buildKey(string $template, array $params): string
    {
        if (!isset(self::CACHE_KEY_TEMPLATES[$template])) {
            throw new \InvalidArgumentException("未定义的缓存键模板: $template");
        }
        
        return sprintf(self::CACHE_KEY_TEMPLATES[$template], ...$params);
    }

    /**
     * 从模板获取分类
     */
    private function getCategoryFromTemplate(string $template): string
    {
        if (strpos($template, 'workflow_') === 0) {
            return 'workflow';
        } elseif (strpos($template, 'permission_') === 0) {
            return 'permission';
        } elseif (strpos($template, 'user_') === 0) {
            return 'user';
        } elseif (strpos($template, 'stats_') === 0) {
            return 'stats';
        } else {
            return 'system';
        }
    }

    /**
     * 预热系统缓存
     */
    private function warmupSystemCache(): void
    {
        // TODO: 预加载系统配置、字典等常用数据
    }

    /**
     * 预热用户缓存
     */
    private function warmupUserCache(array $userIds): void
    {
        // TODO: 预加载活跃用户的权限信息等
    }

    /**
     * 预热统计缓存
     */
    private function warmupStatsCache(): void
    {
        // TODO: 预加载统计数据
    }

    /**
     * 根据模式获取键名列表
     */
    private function getKeysByPattern(string $pattern): array
    {
        // TODO: 实现根据模式获取键名的逻辑
        return [];
    }

    /**
     * 估算内存使用量
     */
    private function estimateMemoryUsage(array $keys): string
    {
        // TODO: 实现内存使用量估算
        return '0 MB';
    }
}
